package pw.goyd.game.server;

import org.jboss.netty.channel.*;
import org.jboss.netty.handler.timeout.IdleState;
import org.jboss.netty.handler.timeout.IdleStateEvent;
import pw.goyd.game.constant.setting.Command;
import pw.goyd.game.handler.CommandReflect;
import pw.goyd.game.handler.imp.EXITGAME;
import pw.goyd.game.handler.imp.EXITROOM;
import pw.goyd.game.logic.SecureResponse;
import pw.goyd.protocol.model.Request;
import pw.goyd.protocol.model.Response;
import pw.goyd.subscribe.PlayerCustomer;

/**
 * 消息路由
 *
 * @author StanWind
 */
public class Router extends SimpleChannelHandler implements Command {
    @Override
    public void channelDisconnected(ChannelHandlerContext ctx,
                                    ChannelStateEvent e) throws Exception {
        //ServerLog.getLogger().debug("channelDisconnected");
        super.channelDisconnected(ctx, e);

    }


    @Override
    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
            throws Exception {
        //ServerLog.getLogger().debug("channelClosed");
        super.channelClosed(ctx, e);

        PlayerCustomer player = LoginList.getPlayer(ctx.getChannel().getId());
        if (player != null) {
            Log.getLogger().debug("强制关闭");
            EXITROOM.process(player);       //	退出房间
            EXITGAME.process(ctx);          //	退出游戏
        }
    }

    @Override
    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
            throws Exception {
        //System.out.println(ctx.getChannel().getId());
        Response response = new Response();
        SecureResponse secureResponse = new SecureResponse();
        response.setCmd(CMD_SECURE);
        response.setData(secureResponse.getBytes());
        ctx.getChannel().write(response);
        //ServerLog.getLogger().debug("Seucre Check");
        super.channelConnected(ctx, e);

    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
            throws Exception {

        PlayerCustomer player = LoginList.getPlayer(ctx.getChannel().getId());
        if (player != null) {
            Log.getLogger().error("ExecptionCaought", e);
            EXITROOM.process(player);       //	退出房间
            EXITGAME.process(ctx);          //	退出游戏
        }
        super.exceptionCaught(ctx, e);
    }

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
            throws Exception {
        Request request = (Request) e.getMessage();
        short cmd = request.getCmd();
        if (cmd != CMD_SECURE)
            Log.getLogger().debug(String.format("cmd---->0x%H", cmd));
        //反射调用处理方法
        CommandReflect.handle(cmd, ctx, request);
    }


    /**
     * 心跳检测
     */
    @Override
    public void handleUpstream(final ChannelHandlerContext ctx, ChannelEvent e)
            throws Exception {

        if (e instanceof IdleStateEvent) {
            if (((IdleStateEvent) e).getState() == IdleState.ALL_IDLE) {
                System.out.println("time out");
                ChannelFuture cf = ctx.getChannel().write(
                        "time out, connection will be closed");
                // when the client received the message,it would be closed
                cf.addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future)
                            throws Exception {
                        // 移除临时客户数据
                        LoginList.removePlayer(ctx.getChannel().getId());
                        // closed connection
                        ctx.getChannel().close();
                    }
                });
            }

        } else {
            super.handleUpstream(ctx, e);
        }
    }


}
